<?php

namespace App\Models;

use App\Http\Controllers\Controller;
use App\Http\Controllers\Live\ServerAPIController;
use App\Http\Controllers\VideoPlayController;
use Exception;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Log;

/**
 * 视频直播模型
 * Class ArticleModel
 * @package app\common\model
 */
class VideoLive extends BaseModel
{
    use HasFactory;

    const CREATED_AT = 'create_time';
    const UPDATED_AT = 'change_time';

    protected $table = 'video_live';



    /*关联视频资源申请*/
    public function conVideoResource()
    {
        return $this->hasMany(VideoLiveResource::class, 'act_id', 'id');
    }

    /**
     * 更新浏览量
     *
     * @param act_id 活动id  
     * @param number 多少次更新一次
     * @param second 大于秒更新一次（取决于后一次请求事件）
     */
    public function updateBrowseNumber($act_id, $number = 100, $second = 300)
    {
        if ($number == 1) {
            return $this->where('act_id', $act_id)->increment('browse_num', 1);
        }

        $key = $act_id . 'video_live_browse_number';
        $res = Cache::pull($key); //从缓存中获取缓存项然后删除，使用 pull 方法，如果缓存项不存在的话返回 null
        $data = [];
        if (empty($res)) {
            $data['number'] = 1;
            $data['create_time'] = time();
            Cache::put($key, $data, 3600 * 24);
        } else {
            //数据大于50或者时间超过5分钟，则更新一次数据
            if ($res['number'] >= $number || time() - $res['create_time'] >= $second) {
                return $this->where('id', $act_id)->increment('browse_num', $res['number'] + 1);
            } else {
                $data['number'] = $res['number'] + 1;
                $data['create_time'] = $res['create_time'];
                Cache::put($key, $data, 3600 * 24);
            }
        }
        return true;
    }

    /**
     * 列表
     * @param limit int 分页大小
     * @param is_play string 是否发布   1 已发布  2 未发布
     * @param keywords string 搜索关键词
     * @param start_time datetime 活动开始时间    数据格式  年月日
     * @param end_time datetime 活动结束时间
     * @param create_start_time datetime 活动创建开始时间   数据格式 年月日时分秒
     * @param create_end_time datetime 活动创建结束时间
     */
    public function lists($field, $keywords, $is_play, $start_time, $end_time, $create_start_time, $create_end_time, $limit = 10)
    {
        if (empty($field)) {
            $field = [
                'id', 'title', 'img', 'host_handle', 'tel', 'browse_num', 'size', 'total_time', 'status', 'push_url',
                'address', 'video_num', 'intro', 'is_play', 'qr_url', 'create_time', 'start_time', 'end_time'
            ];
        }
        $res = $this->select($field)
            ->where(function ($query) use ($keywords) {
                if ($keywords) {
                    $query->where('title', 'like', "%$keywords%");
                }
            })->where(function ($query) use ($is_play, $start_time, $end_time, $create_start_time, $create_end_time) {
                if ($is_play) {
                    $query->where('is_play', $is_play);
                }
                if ($start_time && $end_time) {
                    $query->whereBetween('start_time', [$start_time, $end_time]);
                }
                if ($create_start_time && $create_end_time) {
                    $query->whereBetween('create_time', [$create_start_time, $create_end_time]);
                }
            })
            ->where('is_del', 1)
            // ->orderByDesc('status')
            ->orderByDesc('id')
            ->paginate($limit)
            ->toArray();

        $controllerObj = new Controller();
        $res = $controllerObj->disPageData($res);
        return $res;
    }


    /**
     * 详情
     * @param id int 直播id 或 二维码 token值
     * @param is_play int 是否发布状态
     */
    public function detail($id, $is_play = null, $field = null)
    {
        if (empty($field)) {
            $field = [
                'id', 'cid', 'title', 'img', 'host_handle', 'tel', 'browse_num', 'size', 'total_time', 'status', 'http_pull_url', 'hls_pull_url', 'push_url', 'rtmp_pull_url',
                'address', 'video_num', 'intro', 'is_play', 'qr_url', 'create_time', 'start_time', 'end_time'
            ];
        }
        $res = $this->select($field)
            ->with(['conVideoResource' => function ($query) {
                $query->select('id', 'name', 'act_id', 'video_address', 'format', 'size', 'duration_time')->where('is_del', 1)->orderBy('id');
            }])
            ->where(function ($query) use ($id, $is_play) {
                if ($is_play) {
                    $query->where('is_play', $is_play);
                }
                if (is_numeric($id)) {
                    $query->where('id', $id);
                } else {
                    $query->where('qr_code', $id);
                }
            })
            ->where('is_del', 1)
            ->first();
        if ($res && $res['status'] != 3 && !empty($res['cid'])) {
            $status = $this->getVideoLiveStatus($res);
            if ($status == 3) {
                //禁止推流地址直播
                $serverAPIObj = new ServerAPIController();
                $channelInfo = $serverAPIObj->channelStats($res['cid']);
                if ($channelInfo && ($channelInfo['ret']['status'] == 1 || $channelInfo['ret']['status'] == 3)) {
                    //throw new Exception('正在直播中，切勿关闭直播');
                    $status = 2;
                } else {
                    //现在没直播才能结束
                    $result = $serverAPIObj->channelForbid($res['cid']);
                    if ($result['code'] !== 200) {
                        Log::error('关闭直播失败' . $result['msg']); //'直播推流地址获取失败'
                        return false;
                    }
                }
            }
            //重置活动状态
            if (($status == 2 && $res['status'] == 1) || $status == 3) {
                $res->status = $status;
                $res->save();
            }
            $res['status'] = $status;
        }
        $videoPlayObj = new VideoPlayController();
        foreach ($res['conVideoResource'] as $key => $val) {
            $res['conVideoResource'][$key]['size'] = format_bytes($val['size']);
            $res['conVideoResource'][$key]['duration_time'] = second_to_time(substr($val['duration_time'], 0, strlen($val['duration_time']) - 3));
            $res['conVideoResource'][$key]['video_address'] = $videoPlayObj->getVideoUrl($id, 'video_live_resource', 'video_address');
        }
        return $res;
    }

    /**
     * 获取活动状态
     * $data 活动数组
     * 
     * $status 直播状态  1 未开始直播 2 直播中 3 已结束
     */
    public function getVideoLiveStatus($data)
    {
        if ($data['status'] == 3) {
            return 3;
        }
        $time = date('Y-m-d H:i:s');
        if ($data['end_time'] < $time) {
            $status = 3;
        } else if (($data['start_time'] < $time && $data['end_time'] > $time) || $data['status'] == 2) {
            $status = 2;
        } else {
            $status = 1;
        }
        return $status;
    }
}
